package com.artevivo.managedBeans;

import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;

import org.springframework.stereotype.Controller;

import com.artevivo.entidades.Cliente;
import com.artevivo.services.ClienteService;
import com.artevivo.utilidades.Utilidades;

@Controller(value = "clienteMB")
@RequestScoped
public class ClienteMB implements Serializable {

    private static final long serialVersionUID = -1296935000810441597L;

    @Resource
    private ClienteService clienteService;

    private String nombre;

    private String apellidos;

    private String fechaNacimiento;

    private String direccion;

    private String poblacion;

    private String telefono;

    private String movil;

    private String email;

    private String dni;

    private String iban;

    private String entidad;

    private String sucursal;

    private String dc;

    private String numero;

    public Cliente guardarCliente() {

        Cliente res = null;

        try {
            if (comprobarTelefono() && comprobarCCC()) {
                res = clienteService.guardarCliente(nombre, apellidos, fechaNacimiento, direccion, poblacion, telefono, movil, dni, email, iban,
                        entidad, sucursal, dc, numero);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return res;
    }

    public String calcularEdad(String fecha) {
        return Utilidades.calcularEdad(fecha).toString();
    }

    public void validarDni(FacesContext context, UIComponent componentToValidate, Object value) throws ValidatorException {

        String dni = (String) value;

        // Validacion DNI por expresion regular
        Pattern pat = Pattern.compile("^((([X-Z]|[x-z])[-]?\\d{7}[-]?([A-Z]|[a-z]))|(\\d{8}[-]?([A-Z]|[a-z])))$");
        Matcher mat = pat.matcher(dni);

        if (!mat.matches()) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Formato incorrecto", "Formato incorrecto");
            throw new ValidatorException(message);
        } else {

            // Quitamos posibles guiones
            dni = dni.replaceAll("-", "");
            // Convertimos a matusculas las letras
            dni = dni.toUpperCase();
            // Si es nie, quitamos la primera letra
            if (dni.startsWith("X") || dni.startsWith("Y") || dni.startsWith("Z")) {
                dni = dni.substring(1);
            }
            // Guardamos la ultima letra y la quitamos
            String letra = dni.substring(dni.length() - 1);
            Integer numero = new Integer(dni.substring(0, dni.length() - 1));
            // Posibles letra de un dni
            String letras = "TRWAGMYFPDXBNJZSQVHLCKE";
            // Comprobacion
            numero = numero % 23;
            String referencia = letras.substring(numero, numero + 1);

            if (!referencia.equals(letra)) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "DNI incorrecto", "DNI incorrecto");
                throw new ValidatorException(message);
            }
        }
    }

    public void validarfechaNacimiento(FacesContext context, UIComponent componentToValidate, Object value) throws ValidatorException {

        String fecha = (String) value;

        // Validacion fecha por expresion regular
        Pattern pat = Pattern.compile("^([1-9]|0[1-9]|[12][0-9]|3[01])[- /.]([1-9]|0[1-9]|1[012])[- /.](19|20)\\d\\d$");
        Matcher mat = pat.matcher(fecha);

        if (!mat.matches()) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Formato incorrecto", "Formato incorrecto(dd/mm/aaaa)");
            throw new ValidatorException(message);
        } else {

            Integer edad = Utilidades.calcularEdad(fecha);

            if (edad < 0) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Fecha incorrecta", "Escriba una fecha anterior a hoy");
                throw new ValidatorException(message);
            }
        }
    }

    public Boolean comprobarCCC() {

        Boolean ret = true;

        // Guardamos si estan rellenos los campos
        Boolean ibanNulo = (iban.equals("") || iban == null);
        Boolean entidadNulo = (entidad.equals("") || entidad == null);
        Boolean sucursalNulo = (sucursal.equals("") || sucursal == null);
        Boolean dcNulo = (dc.equals("") || dc == null);
        Boolean numeroNulo = (numero.equals("") || numero == null);

        if (entidadNulo && sucursalNulo && dcNulo && numeroNulo) {

        } else {
            String res = Utilidades.validarCuentaBancaria(entidad + sucursal + dc + numero);

            if (res.equals("FAILDC")) {

                FacesContext.getCurrentInstance().addMessage("formularioAlta:dc",
                        new FacesMessage(FacesMessage.SEVERITY_WARN, "Error", "Numero de cuenta incorrecto"));
                ret = false;
            } else if (res.equals("FAILLONG")) {
                FacesContext.getCurrentInstance().addMessage("formularioAlta:numero",
                        new FacesMessage(FacesMessage.SEVERITY_WARN, "Error", "Falta algun campo en la cuenta"));
                ret = false;
            } else if (ibanNulo) {
                iban = "ES" + Utilidades.calculaDcIban("ES", entidad, sucursal, dc, numero);
            } else if (!iban.equals(iban.substring(0, 2) + Utilidades.calculaDcIban(iban.substring(0, 2), entidad, sucursal, dc, numero))) {
                FacesContext.getCurrentInstance().addMessage("formularioAlta:iban",
                        new FacesMessage(FacesMessage.SEVERITY_WARN, "Error", "Numero de cuenta incorrecto"));
                ret = false;
            }
        }
        return ret;
    }

    public Boolean comprobarTelefono() {
        Boolean res = true;

        if ((telefono == null || telefono.equals("")) && (movil.equals("") || movil == null)) {
            FacesContext.getCurrentInstance().addMessage("formularioAlta:telefono",
                    new FacesMessage(FacesMessage.SEVERITY_WARN, "Error", "Telefono y/o movil obligatorio"));
            FacesContext.getCurrentInstance().addMessage("formularioAlta:movil",
                    new FacesMessage(FacesMessage.SEVERITY_WARN, "Error", "Telefono y/o movil obligatorio"));
            res = false;
        }

        return res;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getApellidos() {
        return apellidos;
    }

    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }

    public String getFechaNacimiento() {
        return fechaNacimiento;
    }

    public void setFechaNacimiento(String fechaNacimiento) {
        this.fechaNacimiento = fechaNacimiento;
    }

    public String getDireccion() {
        return direccion;
    }

    public void setDireccion(String direccion) {
        this.direccion = direccion;
    }

    public String getPoblacion() {
        return poblacion;
    }

    public void setPoblacion(String poblacion) {
        this.poblacion = poblacion;
    }

    public String getTelefono() {
        return telefono;
    }

    public void setTelefono(String telefono) {
        this.telefono = telefono;
    }

    public String getMovil() {
        return movil;
    }

    public void setMovil(String movil) {
        this.movil = movil;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getDni() {
        return dni;
    }

    public void setDni(String dni) {
        this.dni = dni;
    }

    public String getIban() {
        return iban;
    }

    public void setIban(String iban) {
        this.iban = iban;
    }

    public String getEntidad() {
        return entidad;
    }

    public void setEntidad(String entidad) {
        this.entidad = entidad;
    }

    public String getSucursal() {
        return sucursal;
    }

    public void setSucursal(String sucursal) {
        this.sucursal = sucursal;
    }

    public String getDc() {
        return dc;
    }

    public void setDc(String dc) {
        this.dc = dc;
    }

    public String getNumero() {
        return numero;
    }

    public void setNumero(String numero) {
        this.numero = numero;
    }

}
